#ifndef _WH_NET_EVENT_MANAGER_H_
#define _WH_NET_EVENT_MANAGER_H_

#ifdef _MSC_VER
#include "winsocket.h"
#include <WinSock2.h>
#else
#include <sys/epoll.h>
#include <unistd.h>
#endif
#include "common_singleton.h"
#include "base.h"
#include <set>

namespace common
{
	namespace net
	{

		/**
		* @brief 网络事件处理器
		*/
#ifdef _MSC_VER
		class INetEventHandler
		{
		public:
			/**
			* @brief 事件处理
			*
			* @param events 触发的事件
			*/
			virtual void OnNetEvent(int fd, uint32_t events) = 0;
		};
		class CNetEventManager : public CSingleton<CNetEventManager>
		{
		public:

			/**
			* @brief 构造函数
			*/
			CNetEventManager();

			/**
			* @brief 析构函数
			*/
			~CNetEventManager();

			/**
			* @brief 启动管理器
			*
			* @param max_fd_count 支持的最大文件描述符
			*
			* @return 返回启动是否成功
			*/
			int32_t Startup(int32_t max_fd_count);


			/**
			* @brief 关闭管理器
			*
			* @return 返回关闭结果
			*/
			int32_t Shutdown();

			/**
			* @brief 更新网络事件
			*
			* @param timeout 超时时间
			*
			* @return 返回更新结果
			*/
			int32_t OnUpdate(time_t timeout = 10);

			/**
			* @brief 注册事件
			*
			* @param fd 文件描述符
			* @param events 关注的事件
			* @param handler 处理事件的回调
			*
			* @return 返回注册结果
			*/
			int32_t RegisterNetEvent(Socket const * const s1, uint32_t events, INetEventHandler* handler);

			/**
			* @brief 解除注册
			*
			* @param fd 文件描述符
			*
			* @return 解除注册结果
			*/
			int32_t UnregisterNetEvent(int fd);

		private:
			int epoll_fd_;/**<epoll的文件描述符  */
			int32_t max_fd_count_;/**<支持的最大文件描述符  */
			INetEventHandler** event_handler_;
			fd_set all_fd_set_;
			std::set<SOCKET> socket_set_;
		};
#else
		class INetEventHandler
		{
		public:
			/**
			* @brief 事件处理
			*
			* @param events 触发的事件
			*/
			virtual void OnNetEvent(int fd, uint32_t events) = 0;
		};

		/**
		* @brief 网络事件管理器
		*/
		class CNetEventManager : public CSingleton<CNetEventManager>
		{
		public:

			/**
			* @brief 构造函数
			*/
			CNetEventManager();

			/**
			* @brief 析构函数
			*/
			~CNetEventManager();

			/**
			* @brief 启动管理器
			*
			* @param max_fd_count 支持的最大文件描述符
			*
			* @return 返回启动是否成功
			*/
			int32_t Startup(int32_t max_fd_count);


			/**
			* @brief 关闭管理器
			*
			* @return 返回关闭结果
			*/
			int32_t Shutdown();

			/**
			* @brief 更新网络事件
			*
			* @param timeout 超时时间
			*
			* @return 返回更新结果
			*/
			int32_t OnUpdate(time_t timeout = 10);

			/**
			* @brief 注册事件
			*
			* @param fd 文件描述符
			* @param events 关注的事件
			* @param handler 处理事件的回调
			*
			* @return 返回注册结果
			*/
			int32_t RegisterNetEvent(int fd, uint32_t events, INetEventHandler* handler);

			/**
			* @brief 解除注册
			*
			* @param fd 文件描述符
			*
			* @return 解除注册结果
			*/
			int32_t UnregisterNetEvent(int fd);

		private:
			int epoll_fd_;/**<epoll的文件描述符  */
			epoll_event* epoll_events_;/**<epoll事件数组  */
			int32_t max_fd_count_;/**<支持的最大文件描述符  */
			INetEventHandler** event_handler_;
		};
#endif
	}
}


#endif//WH_COMMON_NET_NET_EVENT_MANAGER_H_
